{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1331faa1",
   "metadata": {},
   "source": [
    "可以在[Bookshop.org](https://bookshop.org/a/98697/9781098155438) 和\n",
    "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)获取纸制版和电子版的*Think Python 3e*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1a0a6ff4",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from os.path import basename, exists\n",
    "\n",
    "def download(url):\n",
    "    filename = basename(url)\n",
    "    if not exists(filename):\n",
    "        from urllib.request import urlretrieve\n",
    "\n",
    "        local, _ = urlretrieve(url, filename)\n",
    "        print(\"Downloaded \" + str(local))\n",
    "    return filename\n",
    "\n",
    "download('https://gitee.com/regentsai/Think_Python_3e_CN/blob/master/thinkpython.py');\n",
    "download('https://gitee.com/regentsai/Think_Python_3e_CN/blob/master/diagram.py');\n",
    "\n",
    "import thinkpython"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0286422",
   "metadata": {},
   "source": [
    "# 第2章:变量和语句\n",
    "\n",
    "在上一章，我们使用运算符书写表达式，执行算术运算。\n",
    "\n",
    "本章你将学习变量和语句，`import`语句和`print`函数。我也将介绍更多关于编程的术语，包括参数和模块。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ac44f0c",
   "metadata": {},
   "source": [
    "## 变量\n",
    "\n",
    "**变量variable**是指向一个值的名字。要创建变量，可以像这样写**赋值语句**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "59f6db42",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 17"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52f187f1",
   "metadata": {},
   "source": [
    "赋值语句有3部分：变量的名字在左边，等号运算符`=`在中间，表达式在右边。在上面的例子中，表达式是一个整数。在下面的例子中，表达式是一个浮点数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1301f6af",
   "metadata": {},
   "outputs": [],
   "source": [
    "pi = 3.141592653589793"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e27e65c",
   "metadata": {},
   "source": [
    "下面的例子中，表达式是一个字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f7adb732",
   "metadata": {},
   "outputs": [],
   "source": [
    "message = 'And now for something completely different'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb5916ea",
   "metadata": {},
   "source": [
    "当你运行赋值语句，不会有输出。Python创建变量并给它一个值，但赋值语句没有直接可见的效果。\n",
    "\n",
    "但是，在创建变量之后，你可以把它作为一个表达式。因此我们可以像这样显示`message`的值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6bcc0a66",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'And now for something completely different'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "message"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3fd81de",
   "metadata": {},
   "source": [
    "你也可以使用变量作为算术运算表达式的一部分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "3f11f497",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n + 25"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6b2dafea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.283185307179586"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 * pi"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97396e7d",
   "metadata": {},
   "source": [
    "你也可以在调用函数时使用变量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "72c45ac5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(pi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6bf81c52",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(message)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "397d9da3",
   "metadata": {},
   "source": [
    "## 状态图\n",
    "\n",
    "书面表示变量的常见方式是用一个箭头将变量名称指向变量的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "2c25e84e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "from diagram import make_binding, Frame\n",
    "\n",
    "binding = make_binding(\"message\", 'And now for something completely different')\n",
    "binding2 = make_binding(\"n\", 17)\n",
    "binding3 = make_binding(\"pi\", 3.141592653589793)\n",
    "\n",
    "frame = Frame([binding2, binding3, binding])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5b27a635",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 362x101 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from diagram import diagram, adjust\n",
    "\n",
    "\n",
    "width, height, x, y = [3.62, 1.01, 0.6, 0.76]\n",
    "ax = diagram(width, height)\n",
    "bbox = frame.draw(ax, x, y, dy=-0.25)\n",
    "# adjust(x, y, bbox)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f40da93",
   "metadata": {},
   "source": [
    "这种图形称为**状态图state diagram**，显示了每个变量所处的状态。我们将在全书使用状态图，表示Python存储变量和值的模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba252c85",
   "metadata": {},
   "source": [
    "## 变量名\n",
    "\n",
    "变量名可以想多长有多长。变量名可以包含字母和数字，但不能以数字开始。大写字母是合法的，但习惯上变量只使用小写字母。\n",
    "\n",
    "变量名中唯一可以使用的半角标点符号是下划线`_`。它通常用于连接多个单词的变量名，例如`your_name`或者`airspeed_of_unladen_swallow`。\n",
    "\n",
    "如果你提供了非法的变量名，你将得到语法错误。`million!`是非法的，因为它包含标点符号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ac2620ef",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (4061783710.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[12], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    million! = 1000000\u001b[0m\n\u001b[0m           ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "million! = 1000000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1cefe3e",
   "metadata": {},
   "source": [
    "`76trombones`是非法的，因为它以数字开始。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1a8b8382",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid decimal literal (3636686625.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[13], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    76trombones = 'big parade'\u001b[0m\n\u001b[0m     ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid decimal literal\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "76trombones = 'big parade'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94aa7e60",
   "metadata": {},
   "source": [
    "`class`也是非法的，但错误原因可能不明显。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "b6938851",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (3285659805.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[14], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    class = 'Self-Defence Against Fresh Fruit'\u001b[0m\n\u001b[0m          ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "class = 'Self-Defence Against Fresh Fruit'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "784cfb5c",
   "metadata": {},
   "source": [
    "事实上`class`是一个**关键字keyword**。关键字是python用来指定程序结构的特殊单词。\n",
    "\n",
    "关键字不能用于变量名。\n",
    "\n",
    "以下是python的完整关键字列表。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "127c07e8",
   "metadata": {},
   "source": [
    "```\n",
    "False      await      else       import     pass\n",
    "None       break      except     in         raise\n",
    "True       class      finally    is         return\n",
    "and        continue   for        lambda     try\n",
    "as         def        from       nonlocal   while\n",
    "assert     del        global     not        with\n",
    "async      elif       if         or         yield\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4a8f4b3e",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "35"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from keyword import kwlist\n",
    "\n",
    "len(kwlist)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f14d301",
   "metadata": {},
   "source": [
    "你不需要记住这个列表。在大多数IDE中，关键字的颜色是不一样的；如果你想用关键字定义变量名，你会发现的。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c954a3b0",
   "metadata": {},
   "source": [
    "## 导入语句\n",
    "\n",
    "为了使用一些Python功能，你需要**导入import**它们。例如，下面的语句将导入`math`模块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "98c268e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea4f75ec",
   "metadata": {},
   "source": [
    "**模块module**是变量和函数的集合。math模块提供变量`pi`，包含数学常数$\\pi$。我们可以像这样显示它的值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "47bc17c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.141592653589793"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.pi"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c96106e4",
   "metadata": {},
   "source": [
    "要使用模块中的变量，你需要在模块名和变量名之间使用**点号运算符dot operator** (`.`)。\n",
    "\n",
    "math模块也包含函数。例如，`sqrt`计算平方根。\n",
    "\n",
    "译注：`math.sqrt`函数的定义域为非负数。cmath模块和python标准算术运算符在复数域进行计算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "fd1cec63",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.sqrt(25)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "185e94a3",
   "metadata": {},
   "source": [
    "`pow(m, n)`计算m的n次幂。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "87316ddd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "25.0"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.pow(5, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6fcd96a3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.2246467991473532e-16j"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import cmath\n",
    "cmath.e**(1j*cmath.pi)+1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5df25a9a",
   "metadata": {},
   "source": [
    "现在我们知道了计算幂数的两种方式：使用`math.pow`函数，或者使用幂运算符`**`。\n",
    "\n",
    "两种方式都可以，但运算符的使用频率远比对应函数高。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6538f22b",
   "metadata": {},
   "source": [
    "## 表达式和语句\n",
    "\n",
    "目前我们看到了几种表达式。表达式可以是单个值，例如一个整数，浮点数或者字符串；表达式也可以是一组值和运算符的组合。它还可以包含变量名与函数调用。\n",
    "\n",
    "以下是一个包含这些元素的表达式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "7f0b92df",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "19 + n + round(math.pi) * 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "000dd2ba",
   "metadata": {},
   "source": [
    "我们也看到了几种语句。**语句statement**是代码的一个单元，会产生效果，但没有值。例如，赋值语句创建一个变量并给它提供值，但赋值语句本身没有值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "b882c340",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 17"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cff0414b",
   "metadata": {},
   "source": [
    "与此类似，导入语句会产生效果：导入模块，让我们使用其中的变量和函数，但导入语句没有可见的效果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "299817d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2aeb1000",
   "metadata": {},
   "source": [
    "计算表达式的值称作**求值evaluation**。运行一个语句称作**执行execution**。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f61601e4",
   "metadata": {},
   "source": [
    "## print函数\n",
    "\n",
    "当你对表达式求值时，结果会被显示。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "805977c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "18"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n + 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "efacf0fa",
   "metadata": {},
   "source": [
    "但当你对多个表达式求值时，只有最后一个的值会被显示。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "962e08ab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n + 2\n",
    "n + 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf2b991d",
   "metadata": {},
   "source": [
    "要显示多个值，你可以使用`print`函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "a797e44d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "19\n",
      "20\n"
     ]
    }
   ],
   "source": [
    "print(n+2)\n",
    "print(n+3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29af1f89",
   "metadata": {},
   "source": [
    "该函数对浮点数和字符串也有效。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "73428520",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pi的值大约是\n",
      "3.141592653589793\n"
     ]
    }
   ],
   "source": [
    "print('pi的值大约是')\n",
    "print(math.pi)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b4d7f4a",
   "metadata": {},
   "source": [
    "你也可以使用逗号分隔一组表达式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "9ad5bddd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pi的值大约是 3.141592653589793\n"
     ]
    }
   ],
   "source": [
    "print('pi的值大约是', math.pi)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af447ec4",
   "metadata": {},
   "source": [
    "注意`print`函数会在多个值之间添加空格。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c73a2fa",
   "metadata": {},
   "source": [
    "## 参数\n",
    "\n",
    "当你调用函数时，括号中的表达式称为**参数argument**。我们目前看过的有些函数只接受1个参数，例如`int`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "060c60cf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "101"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int('101')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4ad4f2c",
   "metadata": {},
   "source": [
    "有些函数接受两个参数，例如`math.pow`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "2875d9e0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "25.0"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.pow(5, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17293749",
   "metadata": {},
   "source": [
    "有些函数接受额外的可选参数。例如，`int`可以接受第2个参数，指定数字的基数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "43b9cf38",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int('101', 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c95589a1",
   "metadata": {},
   "source": [
    "基数为2的数字序列`101`对应十进制的数字5。\n",
    "\n",
    "`round`也接受可选的第2个参数，可以指定近似到小数点后几位。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "e8a21d05",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.142"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(math.pi, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21e4a448",
   "metadata": {},
   "source": [
    "有些函数可以接受任意数量的参数，例如`print`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "724128f4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Any number of arguments\n"
     ]
    }
   ],
   "source": [
    "print('Any', 'number', 'of', 'arguments')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "667cff14",
   "metadata": {},
   "source": [
    "如果你调用一个函数，提供了过多参数，将产生`TypeError`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "69295e52",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "float expected at most 1 argument, got 2",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31mTypeError\u001b[0m\u001b[0;31m:\u001b[0m float expected at most 1 argument, got 2\n"
     ]
    }
   ],
   "source": [
    "%%expect TypeError\n",
    "\n",
    "float('123.0', 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5103368e",
   "metadata": {},
   "source": [
    "如果你提供的参数太少，也将产生`TypeError`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "edec7064",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "pow expected 2 arguments, got 1",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31mTypeError\u001b[0m\u001b[0;31m:\u001b[0m pow expected 2 arguments, got 1\n"
     ]
    }
   ],
   "source": [
    "%%expect TypeError\n",
    "\n",
    "math.pow(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5333c416",
   "metadata": {},
   "source": [
    "如果函数无法处理你提供的参数的类型，也将产生`TypeError`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "f86b2896",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "must be real number, not str",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31mTypeError\u001b[0m\u001b[0;31m:\u001b[0m must be real number, not str\n"
     ]
    }
   ],
   "source": [
    "%%expect TypeError\n",
    "\n",
    "math.sqrt('123')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "548828af",
   "metadata": {},
   "source": [
    "在你开始学习的时候这种检查可能很恼人，但它会帮助你检测和纠正错误。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be2b6a9b",
   "metadata": {},
   "source": [
    "## 注释\n",
    "\n",
    "当程序变得更大更复杂，它们会变得更难阅读。形式语言很紧密，通常看到一段代码很难明白它在干什么以及为什么这样做。\n",
    "\n",
    "出于这个原因，将注解加入你的程序，用自然语言解释程序在干什么是个好主意。这些注解称为**注释comments**，以`#`符号作为开端。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "607893a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 42分42秒对应的秒数\n",
    "seconds = 42 * 60 + 42"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "519c83a9",
   "metadata": {},
   "source": [
    "在这个例子里，注释单独处于一行。你也可以将注释放在代码行的末尾："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "615a11e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "miles = 10 / 1.61     # 10km对应的英里数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87c8d10c",
   "metadata": {},
   "source": [
    "从`#`开始到该行结尾的所有内容都被忽略，它对程序的执行没有影响。\n",
    "\n",
    "注释在说明代码中不明显的功能时最有用。可以合理地假定阅读者能明白这段代码*是什么*；而解释代码*为什么*这么设计会更有用。\n",
    "\n",
    "下面的注释是对代码的重复，没有用处："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "cc7fe2e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = 8     # 将8赋值给v"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb83b14a",
   "metadata": {},
   "source": [
    "下面的注释包含了代码中没有的有用信息："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "7c93a00d",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = 8     # 速度，单位为英里/小时"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cd60d4f",
   "metadata": {},
   "source": [
    "好的变量名可以减少注释的需求，但过长的变量名将让复杂的表达式难以阅读，所以需要权衡。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d61e416",
   "metadata": {},
   "source": [
    "## 调试\n",
    "\n",
    "程序中会出现3种错误：语法错误，运行时错误和语义错误。为了更快地处理它们，有必要分辨它们。\n",
    "\n",
    "- **语法错误Syntax error**：“语法”指的是代码中的结构和关于结构的规则。如果程序中出现语法错误，Python不会运行程序。它将立刻显示错误信息。\n",
    "- **运行时错误Runtime error**：如果程序中没有语法错误，就可以运行。但在运行过程中如果有些东西出错，Python将显示错误信息并终止程序。这种类型称为运行时错误。它也叫作**异常exception**，因为有些意料之外的事情发生了。\n",
    "- **语义错误Semantic error**：“语义”即含义。如果程序中出现语义错误，程序能够运行且不会产生错误信息，但不会按你的意愿执行。识别语义错误可能很棘手，因为需要你回过头去观察程序输出并尝试理解它做了什么。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cd52721",
   "metadata": {},
   "source": [
    "我们可以看到，一个非法的变量名将导致语法错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "86f07f6e",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (4061783710.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[39], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    million! = 1000000\u001b[0m\n\u001b[0m           ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "million! = 1000000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8971d33",
   "metadata": {},
   "source": [
    "如果你给运算符提供不支持的类型，将产生运行时错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "682395ea",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unsupported operand type(s) for /: 'str' and 'int'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31mTypeError\u001b[0m\u001b[0;31m:\u001b[0m unsupported operand type(s) for /: 'str' and 'int'\n"
     ]
    }
   ],
   "source": [
    "%%expect TypeError\n",
    "\n",
    "'126' / 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e51fa6e2",
   "metadata": {},
   "source": [
    "最后是一个语义错误的例子。假设我们想要计算`1`和`3`的平均值，但我们忘记了运算符的优先级，像这样写："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "2ff25bda",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.5"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 + 3 / 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0828afc0",
   "metadata": {},
   "source": [
    "当对这个表达式求值时，不会产生错误信息，因此没有语法错误或者运行时错误。但是产生的结果并非`1`和`3`的平均值，因此这个程序不正确。这是一个语义错误，因为程序没有按照我们的意图运行。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07396f3d",
   "metadata": {},
   "source": [
    "## 术语表\n",
    "\n",
    "- **变量variable**：指向一个值的名字。\n",
    "- **赋值语句assignment statement**：将一个值与变量进行绑定的语句。\n",
    "- **状态图state diagram**：表示一组变量和他们指向的值的图形化表示方式。\n",
    "- **关键字keyword**：用于指定程序结构的特殊单词。\n",
    "- **导入语句import statement**：读取模块文件，让我们可以使用其中变量和函数的语句。\n",
    "- **模块module**：包含Python代码的文件，包含函数定义和其他语句。\n",
    "- **点运算符dot operator**：`.`运算符，通常用来获取模块中的函数和变量，语法为`模块.函数名`。\n",
    "- **求值evaluate**：执行表达式中的运算，计算表达式的值\n",
    "- **语句statement**：表示一个命令或者动作的若干行代码。\n",
    "- **执行execute**：运行语句，按语句的要求进行操作。\n",
    "- **参数argument**：当函数被调用时，提供给函数的值。\n",
    "- **注释comment**：程序中包含的文本，提供关于程序的信息，但对程序的执行没有影响。\n",
    "- **运行时错误runtime error**：导致程序在运行期间显示错误信息并退出程序的错误。\n",
    "- **异常exception**：运行程序时被检测出来的错误。\n",
    "- **语义错误semantic error**：导致程序执行错误，但是不会显示错误信息的错误。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70ee273d",
   "metadata": {},
   "source": [
    "## 练习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "c9e6cab4",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Exception reporting mode: Verbose\n"
     ]
    }
   ],
   "source": [
    "# 这个单元格让Jupyter在出现运行时故障时提供更多调试信息。\n",
    "# 在进行练习前先运行本单元格。\n",
    "\n",
    "%xmode Verbose"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7256a9b2",
   "metadata": {},
   "source": [
    "### 询问虚拟助手\n",
    "\n",
    "我鼓励你们使用虚拟助手学习本章中的任何话题。\n",
    "\n",
    "如果你好奇我列出的关键字，你可以询问“为什么class是一个关键字？”或者“为什么变量名不能是关键字？”\n",
    "\n",
    "你可能注意到`int`, `float`和`str`不是Python的关键字。这些是表示类型的变量，而且可以当作函数使用。因此自定义一个与它们同名的变量或者函数是*合法*的，但是强烈不推荐这种方式。询问虚拟助手“使用int，float,str作为变量名会导致哪些问题？”\n",
    "\n",
    "另外可以询问“Python内建(built-in)的函数有哪些？”如果你对某些函数好奇，进一步询问。\n",
    "\n",
    "本章我们导入`math`模块，使用了其中的部分函数和变量。询问“math模块中有哪些变量和函数？”以及“除了math模块，哪些模块被认为是Python的核心模块？”"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f92afde0",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "正如我前一章的建议所说，当你学习新功能时，你应该故意制造错误，看看会发生什么。\n",
    "\n",
    "- `n = 17`是合法的语句。那么`17 = n`呢?\n",
    "- `x = y = 1`是合法的语句吗?\n",
    "- 在某些语言中每个语句以分号`;`作为结尾。如果你在Python语句的结尾添加分号会怎样？\n",
    "- 如果在语句的结尾添加句点会怎样？\n",
    "\n",
    "- 如果你拼错了模块的名字，导入了`maath`会怎样？"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d562609",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "将Python解释器当成计算器，进行练习：\n",
    "\n",
    "\n",
    "**第1部分**：半径为$r$的球体体积为$\\frac{4}{3} \\pi r^3$。半径为5的球体体积为多少？用变量`radius`存储半径，将体积计算结果赋值给变量`volume`。\n",
    "\n",
    "显示体积结果。添加注释，说明`radius`的单位为厘米，`volume`的单位为立方厘米。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6449b12b",
   "metadata": {},
   "source": [
    "**第2部分**：对于任意的$x$, $(\\cos x)^2 + (\\sin x)^2 = 1$。让我们看看对于指定的$x$，例如42,该等式是否成立。\n",
    "\n",
    "创建一个变量`x`，将42赋值给这个变量。然后使用`math.cos`和`math.sin`计算$x$的正弦值和余弦值，并将它们的平方相加。\n",
    "\n",
    "运算结果应该接近1。它可能不是刚好为1，因为浮点数的算术不是精确值，它只能近似正确。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4986801f",
   "metadata": {},
   "source": [
    "**第3部分**：除了`pi`,`math`模块还定义了自然常数`e`。如果你不熟悉，可以询问\"`math.e`是什么？\"。现在用3种方式计算$e^2$:\n",
    "\n",
    "- 使用`math.e`和幂运算符(`**`)。\n",
    "- 使用`math.pow`计算`math.e`的`2`次方.\n",
    "- 使用`math.exp`，该函数接受参数$x$，计算$e^x$。\n",
    "\n",
    "你可能会发现最后一个结果与其他两个有点不同。尝试看看你是否能发现，哪个是正确的。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7f4edf8",
   "metadata": {
    "tags": []
   },
   "source": [
    "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n",
    "\n",
    "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n",
    "\n",
    "Code license: [MIT License](https://mit-license.org/)\n",
    "\n",
    "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "cctbx",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
